package comframe.jdbc.sql.support;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import comframe.jdbc.sql.convert.ConvertUtil;
import comframe.jdbc.sql.datasource.Config;
import comframe.jdbc.sql.datasource.ConnFactory;
import comframe.jdbc.sql.datasource.RayDataSource;
import comframe.jdbc.sql.support.struct.RM;

public class JdbcEx implements IEx{
	private static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(JdbcEx.class);
	private Connection conn = null;
	private PreparedStatement  pstm= null;
	private ResultSet  rs= null;
	private Config config;
	private RayDataSource dataSource;
	private boolean IsSingleton;
	public JdbcEx(Config config,boolean IsSingleton){
		this.config = config;
		this.IsSingleton = IsSingleton;
	}
	
	public JdbcEx(boolean IsSingleton){
		this.IsSingleton = IsSingleton;
	}
	
	public JdbcEx(RayDataSource dataSource,boolean IsSingleton) {
		this.dataSource = dataSource;
		this.IsSingleton = IsSingleton;
		this.config = dataSource.getConfig();
	}

	public void init() throws Exception {
		try {
			if(!IsSingleton || conn == null){
				if(dataSource!=null){
					 if(dataSource.getComboPooledDataSource() ==null){
						 conn = dataSource.createDataSource().getConnection();
					 }else{
						 conn = dataSource.getComboPooledDataSource().getConnection();
					 }
					conn.setAutoCommit(dataSource.isAutoCommit());
				}else if(config!=null)
						conn = ConnFactory.getFactory().getConn(config);
						conn.setAutoCommit(config.isAutoCommit());
			}
		} catch (Exception e) {
			logger.info("数据库连接异样,从新连接数据库");
			//init();
		}
		
	}

	public void destory() {
		if(!IsSingleton){
			if(conn!=null){
				try {
						conn.close();
						conn = null;
				} catch (SQLException e) {
					logger.error("conn 关闭失败");
				}
			}
		}
		
		if(pstm != null){
			try {
				pstm.close();
				pstm = null;
			} catch (SQLException e) {
				logger.error("rs 关闭失败");
			}
		}
		
		if(rs != null){
			try {
				rs.close();
				rs = null;
			} catch (SQLException e) {
				logger.error("rs 关闭失败");
			}
		}
	}

	public void commit() throws SQLException {
		if(!config.isAutoCommit()){
			conn.commit();
			conn.setAutoCommit(false);
		}
	}

	public void rollback() throws SQLException {
		if(!config.isAutoCommit()){
			if(conn != null){
				conn.rollback();
			}
		}
	}
   /**
    * 插入语句
    */
	public boolean insert(RM rm) throws SQLException {
		//打印SQL
		showParams(rm);
		//执行Sql
		pstm = conn.prepareStatement(rm.getSql());
		int i = 1;
		if(rm.getParams()!=null)
			for(Object object :rm.getParams()){
				pstm.setObject(i++, object);
			}
		 if(pstm.executeUpdate() != 1){
			 return false;
		 }
		 return true;
	}
    /**
     * 查询语句
     */
	public List<Object> find(RM rm) throws Exception {
		//打印SQL
		showParams(rm);
		//执行Sql
		pstm = conn.prepareStatement(rm.getSql());
		int i = 1;
		if(rm.getParams()!=null)
			for(Object object :rm.getParams()){
				pstm.setObject(i++, object);
			}
		return ConvertUtil.RsConverToObject(pstm.executeQuery(),rm.getClazz());
	}

	public boolean delete(RM rm) throws SQLException {
		//打印SQL
		showParams(rm);
		//执行Sql
		pstm = conn.prepareStatement(rm.getSql());
		int i = 1;
		if(rm.getParams()!=null)
			for(Object object :rm.getParams()){
				pstm.setObject(i++, object);
			}
		 if(pstm.executeUpdate() != 1){
			 return false;
		 }
		 return true;
	}

	public Integer count(RM rm) throws SQLException {
		//打印SQL
		showParams(rm);
		//执行Sql
		pstm = conn.prepareStatement(rm.getSql());
		int i = 1;
		if(rm.getParams()!=null)
			for(Object object :rm.getParams()){
				pstm.setObject(i++, object);
			}
		return ConvertUtil.RsConverToCount(pstm.executeQuery(),rm.getClazz());
	}

	private void showParams(RM rm) {
		if((config!=null&&config.isShowSql())||(dataSource!=null&&dataSource.isShowSql())){
			logger.info("[SQL]："+rm.getSql());
		}
	}

	public List<Object> pageQuery(RM rm) throws Exception {
		//打印SQL
		showParams(rm);
		//执行Sql
		pstm = conn.prepareStatement(rm.getSql());
		int i = 1;
		if(rm.getParams()!=null)
			for(Object object :rm.getParams()){
				pstm.setObject(i++, object);
			}
		return ConvertUtil.RsConverToObject(pstm.executeQuery(),rm.getClazz());
	}

	public boolean update(RM rm) throws SQLException {
		//打印SQL
		showParams(rm);
		//执行Sql
		pstm = conn.prepareStatement(rm.getSql());
		int i = 1;
		if(rm.getParams()!=null)
			for(Object object :rm.getParams()){
				pstm.setObject(i++, object);
			}
		 if(pstm.executeUpdate() != 1){
			 return false;
		 }
		 return true;
	}

	@Override
	public boolean insertBatch(List<RM> rms) throws Exception {
		for(RM rm :rms){
			//打印SQL
			showParams(rm);
			//执行Sql
			pstm = conn.prepareStatement(rm.getSql());
			int i = 1;
			if(rm.getParams()!=null)
				for(Object object :rm.getParams()){
					pstm.setObject(i++, object);
				}
			 if(pstm.executeUpdate() != 1){
				 return false;
			 }
			 if(pstm != null)pstm.close();
		}
		return true;
	}
	
    
}
